/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package estsapp.controladores.ABMMaterial;


import estsapp.controladores.ABMProducto.ModeloTablaNivelStock;
import estsapp.controladores.Controlador;
import estsapp.controladores.ControladorPrincipal;
import estsapp.controladores.FabricaControladores;
import estsapp.entidades.Material;
import estsapp.entidades.ModeloGestionStock;
import estsapp.entidades.Precio;
import estsapp.entidades.Proveedor;
import estsapp.entidades.TipoMaterial;
import estsapp.expertos.ExpertoABMMaterial;
import estsapp.expertos.FabricaExpertos;
import estsapp.expertos.excepciones.ABMMaterialException;
import estsapp.utiles.filtrosTexto.AgregarFiltroTextField;
import estsapp.utiles.modeloComboGenerico.ModeloComboGenerico;
import estsapp.utiles.modeloTabla.ModeloTabla;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import persistencia.exceptions.ExcepcionFachada;

/**
 *
 *
 * @author diego
 */
public class ControladorABMMaterial implements Controlador {

    private PantallaABMMaterial pantalla;
    private ExpertoABMMaterial experto;
    private Material materialSeleccionado;
    private boolean iniciado;
    private ActualizarPrecioMaterialJDialog actualziarPrecioJDialog;
    private boolean modificarPrecio;
    private NivelesStockJdialog nivelesJDialog;
    public ControladorABMMaterial() {
        pantalla = new PantallaABMMaterial();
        experto = (ExpertoABMMaterial) FabricaExpertos.getInstancia().getExperto(FabricaExpertos.expertos.ABM_MATERIAL);
        actualziarPrecioJDialog = new ActualizarPrecioMaterialJDialog(null, true);
        actualziarPrecioJDialog.setLocationRelativeTo(null);
        
        nivelesJDialog = new NivelesStockJdialog(null, true);
        nivelesJDialog.setLocationRelativeTo(null);
        
        nivelesJDialog.getTblNiveles().setModel(new ModeloTablaNivelStock());

        pantalla.getTblMateriales().setModel(new ModeloTablaMateriales());
        pantalla.getTblMateriales().setAutoCreateRowSorter(true);
        pantalla.getTblMateriales().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                seleccionarMaterial();
            }
        });
        pantalla.getTblPrecioProveedor().setModel(new ModeloTablaPrecioProveedor());
        pantalla.getBtnAgregarPrecioProveedor().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                agregarPrecioMaterial();
            }
        });
        pantalla.getTxtPrecioProveedor().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                agregarPrecioMaterial();
            }
        });
        AgregarFiltroTextField.filtroNumeroDecimal(pantalla.getTxtTamaño(), 3);
        AgregarFiltroTextField.filtroNumeroDecimal(pantalla.getTxtPrecioProveedor(), 3);
        AgregarFiltroTextField.filtroNumeroDecimal(pantalla.getTxtCostoAlmacenamiento(), 3);
        AgregarFiltroTextField.filtroNumeroDecimal(pantalla.getTxtCostoPedido(), 3);

        pantalla.getBtnModificar().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (pantalla.getTblPrecioProveedor().getSelectedRow() != -1) {
                    mostrarDialogoModificarPrecio(true);
                }
            }
        });
        pantalla.getTxtDescripcion().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                guardar();
            }
        });
        pantalla.getBtnActualizar().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (pantalla.getTblPrecioProveedor().getSelectedRow() != -1) {
                    mostrarDialogoModificarPrecio(false);
                }
            }
        });
        pantalla.getBtnEliminar().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (pantalla.getTblPrecioProveedor().getSelectedRow() != -1) {
                    quitarPrecio();
                }
            }
        });

        pantalla.getBtnNuevoTipoMat().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                iniciarABMTipoMaterial();
            }
        });
        
        pantalla.getBtnNuevoProveedor().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                iniciarABMProveedor();
            }
        });
        
        pantalla.getTxtPrecioProveedor().addFocusListener(new FocusAdapter() {
            @Override
            public void focusLost(FocusEvent e) {
                if (pantalla.getCbxProveedor().getSelectedIndex() > 0 && pantalla.getTxtPrecioProveedor().getText().length() > 0) {
                    agregarPrecioMaterial();
                }
            }
        });

        pantalla.getBtnNiveles().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                mostrarNiveles();
            }
        });


        /**
         * ################################################################
         * ################################################################
         * Barra herramientas
         * ################################################################
         * ################################################################
         */
        pantalla.getBtnGuardar().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                guardar();
            }
        });
        pantalla.getBtnNuevo().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                nuevoMaterial();
            }
        });
        pantalla.getBtnBaja().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                darBaja();
            }
        });
        pantalla.getBtnSalir().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                salir();
            }
        });

        /**
         * ################################################################
         * ################################################################
         * JDIALOG Actualizar Precio
         * ################################################################
         * ################################################################
         */
        AgregarFiltroTextField.filtroNumeroDecimal(actualziarPrecioJDialog.getTxtPrecioProveedor(), 3);
        actualziarPrecioJDialog.getBtnAceptar().addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (modificarPrecio) {
                    modificarPrecio();
                } else {
                    actualizarPrecio();
                }
            }
        });

    }

    public boolean isIniciado() {
        return iniciado;
    }

    @Override
    public JInternalFrame getPantalla() {
        return pantalla;
    }

    @Override
    public void iniciar() {
        if (!iniciado) {
            ((ControladorPrincipal) FabricaControladores.getInstance().getControlador(FabricaControladores.controladoresNombre.PRINCIPAL)).agregarPantallaInterna(pantalla);
            iniciado = true;
        } else {
            pantalla.toFront();
            pantalla.setVisible(true);
        }
        pantalla.getCbxTipo().setModel(new ModeloComboGenerico(experto.buscarTipoMateriales()));
        pantalla.getCbxProveedor().setModel(new ModeloComboGenerico(experto.buscarProovedores()));
        pantalla.getCbxModeloGestStock().setModel(new ModeloComboGenerico(experto.buscarModelosStock()));
        ((ModeloTablaMateriales) pantalla.getTblMateriales().getModel()).setListaElementos(experto.buscarMateriales());
        nuevoMaterial();
    }

    public void guardar() {
        materialSeleccionado.setNombre(pantalla.getTxtNombre().getText());
        if (pantalla.getTxtTamaño().getText().length() > 0) {
            materialSeleccionado.setTamaño(Float.valueOf(pantalla.getTxtTamaño().getText()));
        } else {
            materialSeleccionado.setTamaño(null);
        }
        if (pantalla.getCbxUnidadMedida().getSelectedIndex() != 0) {
            materialSeleccionado.setUnidadMedida(pantalla.getCbxUnidadMedida().getSelectedItem().toString());
        } else {
            materialSeleccionado.setUnidadMedida(null);
        }
        if (pantalla.getCbxTipo().getSelectedIndex() > 0) {
            materialSeleccionado.setTipo((TipoMaterial) ((ModeloComboGenerico) pantalla.getCbxTipo().getModel()).getItemSeleccionado());
        }
        materialSeleccionado.setDescripcion(pantalla.getTxtDescripcion().getText());
        materialSeleccionado.setCostoAlmacenamiento(Float.valueOf(pantalla.getTxtCostoAlmacenamiento().getText()));
        materialSeleccionado.setCostoPedido(Float.valueOf(pantalla.getTxtCostoPedido().getText()));
        ModeloGestionStock modeloStock = null;
        if (pantalla.getCbxModeloGestStock().getSelectedIndex() > 0) {
            modeloStock = (ModeloGestionStock) ((ModeloComboGenerico) pantalla.getCbxModeloGestStock().getModel()).getItemSeleccionado();
        }
        materialSeleccionado.getStock().setModelo(modeloStock);
        try {
            experto.guardar(materialSeleccionado);
        } catch (ABMMaterialException ex) {
            JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "INFORMACIÓN", JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        JOptionPane.showMessageDialog(pantalla, "Material Guardado Correctamente", "INFORMACIÓN", JOptionPane.INFORMATION_MESSAGE);
        agregaMaterialTabla(materialSeleccionado);
        limpiarCampos();
        nuevoMaterial();

    }

    private void limpiarCampos() {
        pantalla.limpiarCampos();
    }

    private void seleccionarMaterial() {
        int fila = pantalla.getTblMateriales().getSelectedRow();
        if (fila == -1) {
            return;
        }
        int filaModelo = pantalla.getTblMateriales().convertRowIndexToModel(fila);
        materialSeleccionado = (Material) ((ModeloTablaMateriales) pantalla.getTblMateriales().getModel()).getRow(filaModelo);
        mostrarMaterial(materialSeleccionado);
    }

    private void mostrarMaterial(Material material) {
        limpiarCampos();
        pantalla.getTxtNombre().setText(material.getNombre());
        pantalla.getTxtTamaño().setText(material.getTamaño().toString());
        pantalla.getTxtDescripcion().setText(material.getDescripcion());
        ((ModeloComboGenerico) pantalla.getCbxTipo().getModel()).setItemSeleccionado(material.getTipo());
        pantalla.getCbxUnidadMedida().setSelectedItem(material.getUnidadMedida());
        pantalla.getTxtCostoAlmacenamiento().setText(material.getCostoAlmacenamiento().toString());
        pantalla.getTxtCostoPedido().setText(material.getCostoPedido().toString());
        if (material.getStock().getModelo() != null) {
            ((ModeloComboGenerico) pantalla.getCbxModeloGestStock().getModel()).setItemSeleccionado(material.getStock().getModelo());
        }
        for (Precio precio : material.getPrecios()) {
            if (precio.getFechaHasta() == null) {
                ((ModeloTablaPrecioProveedor) pantalla.getTblPrecioProveedor().getModel()).addRow(precio);
            }
        }
    }

    private void agregaMaterialTabla(Material material) {
        List materiales = ((ModeloTablaMateriales) pantalla.getTblMateriales().getModel()).getListaElementos();
        for (Iterator it = materiales.iterator(); it.hasNext();) {
            Object materialLista = it.next();
            if (material.equals(materialLista)) {
                ((ModeloTablaMateriales) pantalla.getTblMateriales().getModel()).fireTableDataChanged();
                return;
            }
        }
        ((ModeloTablaMateriales) pantalla.getTblMateriales().getModel()).addRow(material);
    }

    private void quitarMaterialTabla(Material material) {
        List materiales = ((ModeloTablaMateriales) pantalla.getTblMateriales().getModel()).getListaElementos();
        for (Iterator it = materiales.iterator(); it.hasNext();) {
            Object materialLista = it.next();
            if (material.equals(materialLista)) {
                ((ModeloTablaMateriales) pantalla.getTblMateriales().getModel()).getListaElementos().remove(material);
                ((ModeloTablaMateriales) pantalla.getTblMateriales().getModel()).fireTableDataChanged();
                return;
            }
        }
    }

    private void agregarPrecioMaterial() {
        Precio precio;
        Proveedor proveedor = (Proveedor) ((ModeloComboGenerico) pantalla.getCbxProveedor().getModel()).getItemSeleccionado();
        if (pantalla.getTxtPrecioProveedor().getText().length() > 0 && pantalla.getCbxProveedor().getSelectedIndex() > 0) {

            for (Object object : ((ModeloTablaPrecioProveedor) pantalla.getTblPrecioProveedor().getModel()).getListaElementos()) {
                if (((Precio) object).getProveedor().equals(proveedor)) {
                    return;
                }
            }

            precio = new Precio();
            precio.setMonto(Float.valueOf(pantalla.getTxtPrecioProveedor().getText()));
            precio.setProveedor(proveedor);
            ((ModeloTablaPrecioProveedor) pantalla.getTblPrecioProveedor().getModel()).addRow(precio);
            materialSeleccionado.addPrecio(precio);
            pantalla.getCbxProveedor().setSelectedIndex(0);
            pantalla.getTxtPrecioProveedor().setText("");
        }
    }

    private void nuevoMaterial() {
        materialSeleccionado = new Material();
        limpiarCampos();
        pantalla.getTxtNombre().requestFocus();
    }

    private void darBaja() {
        if (materialSeleccionado == null) {
            return;
        }
        int confirmado = JOptionPane.showConfirmDialog(
                pantalla,
                "¿Desea dar baja al material: " + materialSeleccionado.getNombre() + "?");
        if (JOptionPane.OK_OPTION == confirmado) {
            try {
                experto.darDeBaja(materialSeleccionado);
            } catch (ABMMaterialException ex) {
                JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "INFORMACIÓN", JOptionPane.INFORMATION_MESSAGE);
                return;
            } catch (ExcepcionFachada ex) {
                JOptionPane.showMessageDialog(pantalla, ex.getMessage(), "ERROR", JOptionPane.ERROR_MESSAGE);
                return;
            }
            JOptionPane.showMessageDialog(pantalla, "El material seleccionado fue dado de baja correctamente", "INFORMACIÓN", JOptionPane.INFORMATION_MESSAGE);
            quitarMaterialTabla(materialSeleccionado);
            limpiarCampos();
            nuevoMaterial();
        }
    }

    private void salir() {
        pantalla.setVisible(false);
    }

    private void mostrarDialogoModificarPrecio(boolean isModificar) {
        modificarPrecio = isModificar;
        actualziarPrecioJDialog.setVisible(true);
    }

    private void modificarPrecio() {
        int fila = pantalla.getTblPrecioProveedor().getSelectedRow();
        Precio precio = (Precio) ((ModeloTablaPrecioProveedor) pantalla.getTblPrecioProveedor().getModel()).getRow(fila);
        precio.setMonto(Float.valueOf(actualziarPrecioJDialog.getTxtPrecioProveedor().getText()));
        actualziarPrecioJDialog.setVisible(false);
        actualziarPrecioJDialog.limpiarCampos();
        modificarPrecio = false;
        guardar();
    }

    private void actualizarPrecio() {
        int fila = pantalla.getTblPrecioProveedor().getSelectedRow();
        Precio precioViejo = (Precio) ((ModeloTablaPrecioProveedor) pantalla.getTblPrecioProveedor().getModel()).getRow(fila);
        Precio nuevoPrecio = new Precio();
        nuevoPrecio.setFechaDesde(new Date());
        nuevoPrecio.setMaterial(precioViejo.getMaterial());
        nuevoPrecio.setMonto(Float.valueOf(actualziarPrecioJDialog.getTxtPrecioProveedor().getText()));
        nuevoPrecio.setProveedor(precioViejo.getProveedor());
        precioViejo.setFechaHasta(new Date());
        actualziarPrecioJDialog.setVisible(false);
        actualziarPrecioJDialog.limpiarCampos();
        modificarPrecio = false;
        ((ModeloTablaPrecioProveedor) pantalla.getTblPrecioProveedor().getModel()).addRow(nuevoPrecio);
        materialSeleccionado.addPrecio(nuevoPrecio);
        ((ModeloTablaPrecioProveedor) pantalla.getTblPrecioProveedor().getModel()).removeElement(precioViejo);
        guardar();
    }

    private void quitarPrecio() {
        int fila = pantalla.getTblPrecioProveedor().getSelectedRow();
        Precio precio = (Precio) ((ModeloTablaPrecioProveedor) pantalla.getTblPrecioProveedor().getModel()).getRow(fila);
        for (int i = 0; i < materialSeleccionado.getPrecios().size(); i++) {
            if (materialSeleccionado.getPrecios().get(i).equals(precio)) {
                materialSeleccionado.getPrecios().remove(i);
                break;
            }
        }
        ((ModeloTablaPrecioProveedor) pantalla.getTblPrecioProveedor().getModel()).removeElement(precio);
        experto.eliminarPrecio(precio);
        guardar();
    }

    private void iniciarABMTipoMaterial() {
        FabricaControladores.getInstance().getControlador(FabricaControladores.controladoresNombre.ABM_TIPO_MATERIAL).iniciar();
    }
    
    private void iniciarABMProveedor(){
        FabricaControladores.getInstance().getControlador(FabricaControladores.controladoresNombre.ABM_PROVEEDOR).iniciar();
    }

    private void mostrarNiveles() {
        ((ModeloTabla)nivelesJDialog.getTblNiveles().getModel()).setListaElementos(experto.buscarNivelesStock());
        nivelesJDialog.setVisible(true);
    }
}
